package org.example.interceptor;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.example.common.AdminSessionBean;
import org.example.common.BusinessCode;
import org.example.common.HygResponse;
import org.example.config.WebConfig;
import org.example.enums.RequestMethodEunm;
import org.example.enums.UserStateEnum;
import org.example.utils.IpUtil;
import org.example.utils.WebKit;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author liyishan
 * @date 2023/4/18 15:48
 */
@Slf4j
public class SafeInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (RequestMethodEunm.OPTIONS.getMethod().equals(request.getMethod())) {
            //浏览器对复杂跨域请求的预请求，试探服务器响应是否正确，跳过
            return false;
        }
        //获取ip
        String ip = IpUtil.getRequestIp(request);
        String uri = request.getRequestURI();

        //授权token
        String authToken = request.getHeader("Authorization");
        //下载、导出等部分接口无法在header中的值，所以将token放在了请求URL地址中
        if (StringUtils.isEmpty(authToken)) {
            authToken = request.getParameter("token");
        }
        if (StringUtils.isEmpty(authToken)) {
            log.info("uri:{} 请求未携带登录token ,\n\tHeaders:{}", uri, WebKit.getHeaders(request));
            WebKit.response(response, new HygResponse(BusinessCode.USER_NOT_LOGIN));
            return false;
        }
        String session = "stringRedisTemplate.opsForValue().get(authToken)";
        if (StringUtils.isEmpty(session)) {
            log.info("uri:{} 请求携带token 未找到对应token ,\n\ttoken:{}", uri, authToken);
            WebKit.response(response, new HygResponse(BusinessCode.USER_NOT_LOGIN));
            return false;
        }
        AdminSessionBean sessionBean = JSON.parseObject(session, AdminSessionBean.class);
        if (sessionBean == null) {
            log.info("uri:{} 请求携带token 未找到对应session 未找到对应的用户信息,\n\tsession:{}", uri, session);
            WebKit.response(response, new HygResponse(BusinessCode.USER_NOT_LOGIN));
            return false;
        }
        if (UserStateEnum.INVALID.getCode().equals(sessionBean.getUserState())) {
            log.info("请求携带token 用户已禁用 ,\n\ttoken:{},\n\tuserId:{}", authToken, sessionBean.getUserId());
            WebKit.response(response, new HygResponse(BusinessCode.USER_STATUS_ERROR, "用户已禁用"));
            return false;
        }
        if (UserStateEnum.PULL_BLACK.getCode().equals(sessionBean.getUserState())) {
            log.info("请求携带token 用户已拉黑 ,\n\ttoken:{},\n\tuserId:{}", authToken, sessionBean.getUserId());
            WebKit.response(response, new HygResponse(BusinessCode.USER_STATUS_ERROR, "用户已拉黑"));
            return false;
        }
        if (!UserStateEnum.VALID.getCode().equals(sessionBean.getUserState())) {
            log.info("请求携带token 用户状态不可用 ,\n\ttoken:{},\n\tuserId:{}", authToken, sessionBean.getUserId());
            WebKit.response(response, new HygResponse(BusinessCode.USER_STATUS_ERROR, "用户状态不可用"));
            return false;
        }

        // Session更新
        //stringRedisTemplate.expire(sessionBean.getSessionToken(), sessionTime, TimeUnit.SECONDS);
        //stringRedisTemplate.expire(HygConfig.Redis.SESSION_ID_KEY + sessionBean.getUserId(), sessionTime, TimeUnit.SECONDS);

        // 白名单(不需要接口鉴权)
        if (WebConfig.match(WebConfig.WHITE_URL_03, uri)) {
            log.info("* white url 03 * ip:{}, uri:{}\n", ip, uri);

        } else {
            // 权限校验
            if (!sessionBean.getUri().contains(uri)) {
                log.info("请求携带token 用户无权访问 ,\n\ttoken:{},\n\tuserId:{},\n\turi:{}", authToken, sessionBean.getUserId(), uri);
                //根据uri去查下接口名
                /*String privilegeName = userServiceFeign.getPrivilegeNameByUri(UserType.OPERATION_TERRACE.getCode(), uri);
                if (StringUtils.isNotBlank(privilegeName)) {
                    WebKit.response(response, new HygResponse(BusinessCode.ERROR_AUTH.getCode(), HygConfig.LEFT_IN_BRACKETS + privilegeName + HygConfig.RIGNT_IN_BRACKETS + "接口无权访问,如需使用请联系管理员"));
                } else {
                    WebKit.response(response, new HygResponse(BusinessCode.ERROR_AUTH));
                }*/
                return false;
            }
        }

        request.setAttribute("sessionUser", sessionBean);

        return true;
    }
}
